﻿// XmlVisualizer
// Copyright (C) 2009  Roman Betík - rbetik@gmail.com

// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

using System;
using System.Xml;
using System.Xml.Linq;

using XmlVisualizer.Controllers;
using XmlVisualizer.Models;
using System.Collections.Generic;

namespace XmlVisualizer.Controllers {
    /// <summary>
    /// Interface that every controller in the application must implement;
    /// defines basic actions that can be done in this application.
    /// </summary>
    public interface IController {
		/// <summary>
		/// Defines the action for view on open file command.
		/// </summary>
		/// <param name="filename">name of the file to open</param>
        void OpenDocument(String filename);
		
		/// <summary>
		/// Defines the action for view on save file command.
		/// </summary>
		/// <param name="filename">name of the file where to save the file</param>
        void SaveDocument(String filename);

		/// <summary>
		/// Defines the action for view on exit command.
		/// </summary>
        void Exit();

		/// <summary>
		/// Change language action.
		/// </summary>
		/// <param name="lang">language string</param>
		void ChangeLanguage(String lang);

		/// <summary>
		/// Remove node action.
		/// </summary>
		/// <param name="node">node to remove</param>
		/// <param name="recursively">indicates whether to remove whole tree under the node</param>
		void RemoveNode(XNode node, bool recursively);
		
		/// <summary>
		/// Add new element.
		/// </summary>
		/// <param name="parentElement">parent of the new element</param>
		/// <param name="elementToAdd">new element</param>
		void AddNewElement(XElement parentElement, XNodeInfo elementToAdd);

		/// <summary>
		/// Connect two nodes - add childNode as a child of parentNode.
		/// </summary>
		/// <param name="parentNode"></param>
		/// <param name="childNode"></param>
		ConnectResult ConnectNodes(XNode parentNode, XNode childNode);

		/// <summary>
		/// Select nodes in the current document.
		/// </summary>
		/// <param name="xpathExpression">XPath expression specifying what to select.</param>
		void SelectNodes(string xpathExpression);

		/// <summary>
		/// When user wants to close the document but not the program.
		/// </summary>
		void Close();

		/// <summary>
		/// Sets element's name.
		/// </summary>
		/// <param name="element">XElement which name to set.</param>
		/// <param name="name">name to set.</param>
		void SetElementName(XElement element, String name);

		/// <summary>
		/// Sets element's namespace.
		/// </summary>
		/// <param name="element">XElement which namspace to set</param>
		/// <param name="newNamespace">new namespace</param>
		void SetElementNamespace(XElement element, String newNamespace);

		/// <summary>
		/// Obsolete - remove.
		/// </summary>
		/// <param name="element"></param>
		void UpdateAttributes(XElement element);

		/// <summary>
		/// Prepare for serialization - mostly add guid attributes to the XDocument so that elements can
		/// be identified.
		/// </summary>
		void PrepareForSerialization();

		/// <summary>
		/// Action after the serialization is done - mostly removing of added attributes.
		/// </summary>
		void SerializationDone();

		/// <summary>
		/// Sets mode.
		/// </summary>
		/// <param name="mode">mode to set</param>
		void SetMode(Mode mode);

		/// <summary>
		/// Adds XNodeInfo into the dictionary.
		/// </summary>
		/// <param name="info"></param>
		void AddNodeInfo(XNodeInfo info);

		/// <summary>
		/// Updates order of the childNodes.
		/// </summary>
		/// <param name="parentElement">parent element of the child nodes</param>
		/// <param name="childNodes">list of reorder child nodes</param>
		void UpdateOrder(XElement parentElement, IEnumerable<XNode> childNodes);

		/// <summary>
		/// Resets model to its starting state.
		/// </summary>
		void ResetModel();

		/// <summary>
		/// Sets prefix of a namespace.
		/// </summary>
		/// <param name="element"></param>
		/// <param name="prefix"></param>
		/// <param name="nameSpace"></param>
		void SetNamespacePrefix(XElement element, String prefix, XNamespace nameSpace);

		/// <summary>
		/// Expands element at a given address.
		/// </summary>
		/// <param name="element">element to expand</param>
		/// <param name="address">its adrress</param>
		/// <param name="range">range which child nodes to show</param>
		/// <param name="depth">how deep to go with the expansion</param>
		void Expand(XElement element, ElementAddress address, String range, int depth);
    }
}

namespace XmlVisualizer.Models {
    /// <summary>
    /// Abstract base class for all the models
    /// </summary>
    public interface IModel {
		/// <summary>
		/// Defines the action for model when opening the file.
		/// </summary>
		/// <param name="filename">name of the file to open</param>
        void OpenFile(String filename);
		/// <summary>
		/// Defines the action for mode when saving the file.
		/// </summary>
		/// <param name="filename">name of the file to save</param>
        void SaveFile(String filename);
		/// <summary>
		/// Defines the action for model when to get xml source text.
		/// </summary>
		/// <returns>string with xml source text</returns>
        String GetXmlText();
		/// <summary>
		/// Defines action when view is closed.
		/// </summary>
		void Close();
    }

	public interface IAppModel : IModel, IXmlModel, IXmlModelEvents, IBigXmlModel {
		event Action ModeChanged;
		void SetMode(Mode mode);
		Mode GetMode();
	}

	public interface IBigXmlModel {
		void Expand(XElement element, ElementAddress address, String range, int depth);
	}

	public interface IXmlModel {
		/// <summary>
		/// Remove node.
		/// </summary>
		/// <param name="node">node to remove.</param>
		/// <param name="recursively">indicates whether to remove whole tree under the node.</param>
		void RemoveNode(XNode node, bool recursively);
		/// <summary>
		/// Adds newElement to the child elements of parentElement.
		/// </summary>
		/// <param name="parentElement">parent element</param>
		/// <param name="newElement">element to add</param>
		void AddNewElement(XElement parentElement, XNodeInfo newElement);
		/// <summary>
		/// Connect two nodes - add childNode as a child of parentNode.
		/// </summary>
		/// <param name="parentNode"></param>
		/// <param name="childNode"></param>
		ConnectResult ConnectNodes(XNode parentNode, XNode childNode);
		/// <summary>
		/// Select nodes in the current document.
		/// </summary>
		/// <param name="xpathExpression">XPath expression specifying what to select.</param>
		void XPathSelection(string xpathExpression);
		/// <summary>
		/// Sets element's name.
		/// </summary>
		/// <param name="element">XElement which name to set.</param>
		/// <param name="name">name to set.</param>
		void SetElementName(XElement element, String name);

		void SetElementNamespace(XElement element, String newNamespace);

		void UpdateAttributes(XElement element);

		void AddGuidAttributes();

		void RemoveGuidAttributes();

		XElement Serialize();

		void Deserialize(XElement root);

		XDocument GetDocument();

		IEnumerable<XElement> GetDocumentParts();

		void AddNodeInfo(XNodeInfo info);

		void UpdateOrder(XElement parentElement, IEnumerable<XNode> childNodes);

		void Reset();

		void SetNamespacePrefix(XElement element, String prefix, XNamespace nameSpace);
	}

	public interface IXmlModelEvents {
		event DocumentChangedDelegate DocumentChanged;
		event Action<object, EventArgs> DocumentSaved;
		event Action<object, EventArgs> DocumentLoaded;
		event Action<object, EventArgs> DocumentLoading;
		event Action<object, DisplayXmlEventArgs> DisplayXml;
		event Action<object, EventArgs> DocumentClosed;
		event Action<object, WellformednessEventArgs> DocumentWellformednessChanged;
		event Action<object, NodeChangedEventArgs> NodeChanged;
		event Action<object, SelectionChangedEventArgs> SelectionChanged;
		event Action<object, XmvEventArgs> SaveXmv;
		event Action<object, XmvEventArgs> OpenXmv;
		event Action<object, ValidityEventArgs> DocumentValidityChanged;
	}
}

namespace XmlVisualizer {
	public enum ConnectResult {
		Success,
		ChildHasParent,
		ParentNodeNotElement,
		None
	}

	public interface IParentDocument {
		Document ParentDocument { get; }
	}
}

namespace XmlVisualizer.DiagramDesigner {
	/// <summary>
	/// Classes that implement this interface are groupable.
	/// </summary>
    public interface IGroupable {
		#region Properties
		/// <summary>
		/// Gets the ID.
		/// </summary>
		Guid ID { get; }
		/// <summary>
		/// Gets or sets the parent id.
		/// </summary>
		Guid ParentID { get; set; }
		/// <summary>
		/// Gets or set the IsGroup property.
		/// </summary>
		bool IsGroup { get; set; }
		#endregion		
    }

	/// <summary>
	/// Common interface for items that can be selected
	/// on the DesignerCanvas; used by DesignerItem and Connection
	/// </summary>
    public interface ISelectable {
		#region Properties
		/// <summary>
		/// Get or sets the IsSelected property.
		/// </summary>
		bool IsSelected { get; set; }
		#endregion		
    }
}